<?php
declare(strict_types=1);

namespace app\common\model;

use think\Model;
use think\facade\Db;
use think\model\concern\SoftDelete;
use app\common\model\Menu as MenuModel;
use app\common\model\RoleMenu as RoleMenuModel;

class Role extends Model
{
    use SoftDelete;  // 使用软删除trait
    
    protected $pk = 'role_id';
    protected $name = 'role';
    
    // 自动时间戳类型
    protected $autoWriteTimestamp = true;
    
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    
    // 定义软删除字段
    protected $deleteTime = 'delete_time';
    protected $defaultSoftDelete = null;
    
    /**
     * 定义与角色菜单的一对多关联
     */
    public function roleMenu()
    {
        return $this->hasMany(RoleMenu::class, 'role_id', 'role_id');
    }
    
    /**
     * 获取角色的菜单权限
     * @param int $roleId
     * @return array
     */
    public function getRoleMenuIds(int $roleId): array
    {
        return RoleMenuModel::where('role_id', $roleId)->column('menu_id');
    }
    
    /**
     * 获取角色的菜单权限（包含按钮）
     * @param int $roleId
     * @return array
     */
    public function getRolePermissions(int $roleId): array
    {
        return Db::name('role_menu rm')
            ->join('menu m', 'm.menu_id = rm.menu_id')
            ->where('rm.role_id', $roleId)
            ->where('m.status', 1)
            ->where('m.perms', '<>', '')
            ->column('m.perms');
    }
    
    /**
     * 保存角色菜单关联
     * @param int $roleId
     * @param array $menuIds
     * @return bool
     */
    public function saveRoleMenus(int $roleId, array $menuIds): bool
    {
        // 先删除原有关联
        RoleMenuModel::where('role_id', $roleId)->delete();
        
        if (empty($menuIds)) {
            return true;
        }
        
        // 添加新的关联
        $data = [];
        foreach ($menuIds as $menuId) {
            $data[] = [
                'role_id' => $roleId,
                'menu_id' => $menuId
            ];
        }
        
        return (new RoleMenuModel())->insertAll($data) > 0;
    }
    
    /**
     * 删除角色及相关数据
     * @param int $roleId
     * @return bool
     */
    public function deleteRole(int $roleId): bool
    {
        // 开启事务
        Db::startTrans();
        try {
            // 删除角色
            $this->where('role_id', $roleId)->delete();
            
            // 删除角色菜单关联
            Db::name('role_menu')->where('role_id', $roleId)->delete();
            
            // 删除管理员角色关联
            Db::name('admin_role')->where('role_id', $roleId)->delete();
            
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            return false;
        }
    }
    
    /**
     * 检查角色是否被管理员使用
     * @param int $roleId
     * @return bool
     */
    public function isRoleUsed(int $roleId): bool
    {
        return Db::name('admin_role')
            ->where('role_id', $roleId)
            ->count() > 0;
    }
    
    /**
     * 获取角色列表（带菜单权限）
     * @param array $where 查询条件
     * @param int $page 页码
     * @param int $pageSize 每页数量
     * @return array
     */
    public function getRoleList(array $where = [], int $page = 1, int $pageSize = 10): array
    {
        // 获取角色列表
        $list = $this->where($where)
            ->field('role_id,name,code,status,remark,create_time,update_time')
            ->order('role_id', 'asc')
            ->paginate([
                'list_rows' => $pageSize,
                'page' => $page
            ]);
        
        // 获取每个角色的菜单权限
        $roles = $list->items();
        foreach ($roles as &$role) {
            $role['menu_ids'] = $this->getRoleMenuIds($role['role_id']);
            $role['permissions'] = $this->getRolePermissions($role['role_id']);
        }
        
        return [
            'list' => $roles,
            'total' => $list->total(),
            'page' => $list->currentPage(),
            'page_size' => $list->listRows()
        ];
    }
} 